package com.zhongwang.mms.module.buy.service;

import com.zhongwang.mms.common.ImportCallBack;
import com.zhongwang.mms.gen.entity.BReportPlan;
import com.zhongwang.mms.gen.entity.BShoppingPlan;
import com.zhongwang.mms.gen.entity.TWarehouseInfo;
import com.zhongwang.mms.gen.entity.User;
import com.zhongwang.mms.gen.mapper.BReportPlanMapper;
import com.zhongwang.mms.gen.mapper.BShoppingPlanMapper;
import com.zhongwang.mms.module.buy.dao.BuyPlanDao;
import com.zhongwang.mms.module.buy.dao.ReportPlanDao;
import com.zhongwang.mms.module.buy.listner.ShoppingPlanListener;
import com.zhongwang.mms.module.buy.model.ReportPlanModel;
import com.zhongwang.mms.module.buy.model.ShoppingPlanImportErrorModel;
import com.zhongwang.mms.module.buy.model.ShoppingPlanModel;
import com.zhongwang.mms.module.system.log.LogService;
import com.zhongwang.mms.util.FileUtils;
import com.zhongwang.mms.util.ShiroUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import static com.zhongwang.mms.util.BeanUtil.copy;

/**
 * @Description: 采购管理 -> 采购计划编辑 Service
 * @Author: China.sgl
 * @Date: 2020/4/7 16:25
 */
@SuppressWarnings("ALL")
@Service
public class EditBuyPlanService {

    @Autowired
    private LogService logService;
    @Autowired
    private BuyPlanDao buyPlanDao;
    @Autowired
    private EditReportPlanService editReportPlanService;
    @Autowired
    private BShoppingPlanMapper bShoppingPlanMapper;
    @Autowired
    private BReportPlanMapper bReportPlanMapper;
    @Autowired
    private ReportPlanDao reportPlanDao;

    @Value("${user.upload.path}")
    private String uploadPath;

    private String msg = "";

    /**
     * 按条件查询提报计划
     *
     * @param shoppingPlanModel 条件
     * @return list
     */
    public List<ShoppingPlanModel> findBuyPlanByQuery(ShoppingPlanModel shoppingPlanModel) {
        if (shoppingPlanModel.getRppProjectCodeArrayStr() != null && !shoppingPlanModel.getRppProjectCodeArrayStr().equals("")) {
            String[] strArray = shoppingPlanModel.getRppProjectCodeArrayStr().split(",");
            shoppingPlanModel.setRppProjectCodeArray(Arrays.asList(strArray));
        }
        return buyPlanDao.findBuyPlanByQuery(shoppingPlanModel);
    }

    /**
     * 查询仓库字典表
     *
     * @return list
     */
    public List<TWarehouseInfo> findStocks() {
        return buyPlanDao.findStocks();
    }

    /**
     * 查询采购计划
     *
     * @param sppId 采购计划ID
     * @param rppId 提报计划ID
     * @return ShoppingPlanModel
     */
    public ShoppingPlanModel findBuyPlanById(Integer sppId, Integer rppId) {
        if (sppId != null && sppId != 0) {
            return buyPlanDao.findBySppId(sppId, rppId);
        } else {
            return buyPlanDao.findByRppId(rppId);
        }
    }

    /**
     * 修改采购计划
     *
     * @param shoppingPlanModel shoppingPlanModel
     * @return 行数
     */
    public int update(ShoppingPlanModel shoppingPlanModel) {
        // 如果没有采购计划，新增采购计划， 并修改对应提报计划的采购计划ID
        if (shoppingPlanModel.getSppId() == null) {
            ReportPlanModel reportPlanModel = editReportPlanService.findReportPlanById(shoppingPlanModel.getRppId());
            shoppingPlanModel.setSppMatCode(reportPlanModel.getRppMatCode());
            shoppingPlanModel.setSppStandardNo(reportPlanModel.getRppStandardNo());
            shoppingPlanModel.setSppCategory(null);
            shoppingPlanModel.setSppProjectCode(reportPlanModel.getRppProjectCode());
            shoppingPlanModel.setSppProjectName(shoppingPlanModel.getSppProjectName());
            shoppingPlanModel.setSppPart(reportPlanModel.getRppPart());
            shoppingPlanModel.setSppDesigner(reportPlanModel.getRppDesigner());
            shoppingPlanModel.setSppCreateTime(reportPlanModel.getRppCreateTime());
            shoppingPlanModel.setSppCreateUser(reportPlanModel.getRppCreateUser());
            shoppingPlanModel.setSppTypeName(reportPlanModel.getRppTypes());
            shoppingPlanModel.setSppTypeId(reportPlanModel.getRppTypeId());
            shoppingPlanModel.setSppImportStatus(1);
            shoppingPlanModel.setSppStatus(1);
            shoppingPlanModel.setSppChangeStatus(0);
            shoppingPlanModel.setSppIntegraFlag(0);
            shoppingPlanModel.setSppPreStatus(0);
            shoppingPlanModel.setSppPlanner(reportPlanModel.getRppPlanner());
            shoppingPlanModel.setSppProdNo(reportPlanModel.getRppProdNo());
            BShoppingPlan before = new BShoppingPlan();
            BShoppingPlan after = new BShoppingPlan();
            copy(shoppingPlanModel, after);
            logService.saveLog("编辑采购计划", before, after);
            bShoppingPlanMapper.insert(after);
            BReportPlan bReportPlan = new BReportPlan();
            bReportPlan.setRppId(shoppingPlanModel.getRppId());
            bReportPlan.setRppSppId(after.getSppId());
            return bReportPlanMapper.updateByPrimaryKeySelective(bReportPlan);
        } else {
            BShoppingPlan before = bShoppingPlanMapper.selectByPrimaryKey(shoppingPlanModel.getSppId());
            BShoppingPlan after = new BShoppingPlan();
            copy(before, after);
            copy(shoppingPlanModel, after);
            logService.saveLog("编辑采购计划", before, after);
            return bShoppingPlanMapper.updateByPrimaryKey(after);
        }
    }

    /**
     * 提交采购计划
     *
     * @param id 主键
     * @return 行数
     */
    public int commitById(Integer id) {
        return commitBuyPlan(id);
    }

    /**
     * 提交采购计划
     *
     * @param id 主键
     * @return 行数
     */
    public int cancelById(Integer id) {
        return cancelBuyPlan(id);
    }

    /**
     * 提交采购计划
     *
     * @param id 主键
     * @return 行数
     */
    public int cancelByIds(Integer[] id) {
        int result = 0;
        for (int i = 0; i < id.length; i++) {
            result += cancelBuyPlan(id[i]);
        }
        return result;
    }

    /**
     * 提交采购计划
     *
     * @param rppIds 主键集合
     * @return 行数
     */
    public int commitInId(Integer[] rppIds) {
        int count = 0;
        // 保存日志，生成采购计划
        for (Integer rppId : rppIds) {
            count += commitBuyPlan(rppId);
        }
        return count == rppIds.length ? 1 : 0;
    }

    /**
     * 提交采购计划
     *
     * @param id 主键
     * @return 行数
     */
    @Transactional(rollbackFor = Exception.class)
    private int commitBuyPlan(Integer id) {
        BShoppingPlan plan = bShoppingPlanMapper.selectByPrimaryKey(id);
        logService.saveLog("提交采购计划", "项目名：" + plan.getSppProjectName() + "<br>物料描述：" + plan.getSppMatDesc());
        buyPlanDao.updateReviewFlagById(id, null);
        reportPlanDao.clearRppChangeMarkBySppId(id);
        return buyPlanDao.updateStatusById(id, 3);
    }

    /**
     * 撤销采购计划
     *
     * @param id 主键
     * @return 行数
     */
    private int cancelBuyPlan(Integer id) {
        BShoppingPlan plan = bShoppingPlanMapper.selectByPrimaryKey(id);
        logService.saveLog("撤销采购计划", "项目名：" + plan.getSppProjectName() + "<br>物料描述：" + plan.getSppMatDesc());
        return buyPlanDao.updateStatusById(id, 1);
    }

    /**
     * 合报采购计划
     *
     * @param sppId 采购计划ID
     * @param ids   主键
     * @param num   数量和
     * @return 行数
     */
    @Transactional(rollbackFor = Exception.class)
    public int merge(Integer sppId, Integer[] ids, Double num) {
        // 新增采购计划
        BShoppingPlan plan = bShoppingPlanMapper.selectByPrimaryKey(sppId);
        plan.setSppId(null);
        plan.setSppNum(num);
        plan.setSppIntegraFlag(1);
        bShoppingPlanMapper.insert(plan);
        // 删除原采购计划
        for (Integer id : ids) {
            buyPlanDao.updateStatusById(id, 0);
        }
        // 更新相应提报计划的采购ID
        return buyPlanDao.updateReportPlan(ids, plan.getSppId());
    }

    /**
     * 采购计划导出
     *
     * @param response
     */
    public void export(HttpServletResponse response) {
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        logService.saveLog("采购计划编辑——导出","用户:【"+user.getName()+"】执行导出操作！");
        String path = uploadPath + user.getAccount() + "/";
        List<ShoppingPlanModel> list = buyPlanDao.findBuyPlan(user.getName());
        for (ShoppingPlanModel shoppingPlanModel : list) {
            shoppingPlanModel.setRppProjectCode(shoppingPlanModel.getRppProjectCode().length() == 8 ? shoppingPlanModel.getRppProjectCode().substring(2) : shoppingPlanModel.getRppProjectCode());
        }
        FileUtils.export(path, "采购计划模板.xls", ShoppingPlanModel.class, "sheet1", list, response);
    }

    /**
     * 导入采购计划
     *
     * @param file 导入文件
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public String importFile(MultipartFile file) {
        try {
            FileUtils.importExcel(file, ShoppingPlanModel.class, new ShoppingPlanListener(buyPlanDao, new ImportCallBack() {
                @Override
                public void onSuccess() {
                    msg = "导入完成";
                }

                @Override
                public void onWarning(List list) {
                    msg = "部份数据无法导入，请点击下载检查数据内容";
                    exportErrorExcel(list);
                }
            }, buyPlanDao.findStocks()));
        } catch (IOException e) {
            return "导入失败";
        }
        logService.saveLog("采购计划编辑", "导入采购计划");
        return msg;
    }

    /**
     * 异常数据导出到Excel
     *
     * @param errorList
     */
    private void exportErrorExcel(List<ShoppingPlanImportErrorModel> errorList) {
        if (errorList.size() <= 0) {
            return;
        }
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        String path = uploadPath + user.getAccount() + "/";
        FileUtils.genExcel(path, "error.xls", ShoppingPlanImportErrorModel.class, "sheet1", errorList);
    }

    /**
     * 判断文件是否存在
     *
     * @param url 文件URL
     * @return 是否存在
     */
    public boolean exist(String url) {
        int i = url.lastIndexOf("files/");
        String path = uploadPath + url.substring(i + 6);
        File file = new File(path);
        if (!file.exists()) {
            return false;
        }
        return true;
    }

    /**
     * 删除采购计划
     *
     * @param id 主键
     * @return 行数
     */
    public int delete(Integer id) {
        buyPlanDao.updateReportPlanRppSppId(id);
        return buyPlanDao.updateStatusById(id, 0);
    }

    /**
     * 变更导出
     *
     * @param shoppingPlanModel 条件
     * @param response          输出流
     */
    public void changeExport(ShoppingPlanModel shoppingPlanModel, HttpServletResponse response) {
        User user = ShiroUtils.getUser();
        logService.saveLog("采购计划编辑——变更导出","用户:【"+user.getName()+"】执行导出操作！");
        String path = uploadPath + user.getAccount() + "/";
        List<ShoppingPlanModel> list = buyPlanDao.findBuyPlan(user.getName());
        FileUtils.export(path, "采购计划变更模板.xls", ShoppingPlanModel.class, "sheet1", list, response);
    }
}
